#ifndef _AL_STRUCTS_H
#define _AL_STRUCTS_H
#include <cmath>

struct alPoint3D{
	double x;
	double y;
	double z;
	alPoint3D(){};
	alPoint3D(double xx,double yy,double zz):x(xx),y(yy),z(zz){};
};

struct alPoint2D{
	double x;
	double y;
	alPoint2D(){};
	alPoint2D(double xx,double yy):x(xx),y(yy){};
};

struct alSSIPoint{
	double x;
	double y;
	double z;
	double value;
	double getR(){return sqrt(x*x+y*y+z*z);}
	void Normalization(){
		double r=getR();
		x/=r;y/=r;z/=r;
	}
	alSSIPoint(double xx,double yy,double zz, double v=0.0, bool n=0):x(xx),y(yy),z(zz),value(v)
		{if(n) Normalization();}
};

struct alArray2D{
	size_t m;
	size_t n;
	double *data;
	alArray2D(unsigned int M, unsigned int N):m(M),n(N){ data = new double[m*n]; }
	double getAt(size_t i, size_t j){return *(data+i*n+j);}
	void setAt(size_t i, size_t j, double v){*(data+i*n+j)=v;}
	~alArray2D(){if(data) delete []data;}
	void Zeros(){
		for(size_t i=0;i<m;i++)
			for(size_t j=0;j<n;j++)
				setAt(i,j,0.0);
	}
	void Dump(){
		std::cout<<"dumping matrix"<<std::endl;
		for(size_t i=0;i<m;i++){
			for(size_t j=0;j<n;j++)
				std::cout<<getAt(i,j)<<' ';
			std::cout<<std::endl;
		}
	}

	static alArray2D* read(LPCTSTR filename){
		std::ifstream ifs(filename);
		if(!ifs)
			return 0;
		size_t m,n;
		ifs>>m>>n;
		alArray2D *ret = new alArray2D(m,n);
		if(!ret)
			return 0;
		for(size_t i=0;i<m;i++){
			for(size_t j=0;j<n;j++){
				double tmp;
				ifs>>tmp;
				ret->setAt(i,j,tmp);
				//(*coef)->Dump();
			}

		}
		ifs.close();
		return ret;
	}
};
#define AL_GET_MAX(x,y) (x)>(y)?(x):(y);
#define AL_GET_MIN(x,y) (x)<(y)?(x):(y);

#endif